<?php

namespace App\Jobs;

use App\Enums\DnsType;
use App\Enums\DomainType;
use App\Facades\AliyunCdn;
use App\Facades\AliyunDcdn;
use App\Facades\AliyunDns;
use App\Models\Certificate;
use App\Models\DomainPool;
use Illuminate\Support\Str;

class AutoCreateSslCert extends BaseJob
{
    public string $queue = 'aliyun';

    public function __construct(protected DomainPool $pool)
    {
    }

    public function handle(): void
    {
        $acme = app('acme');
        $order = $acme->createOrder([$this->pool->domain]);
        $authorizations = $acme->authorize($order);

        foreach ($authorizations as $authorization) {
            $txtRecord = $authorization->getTxtRecord();
            $txtRecord->getName();

            $rr = Str::remove($this->pool->root, $txtRecord->getName());
            $rr = rtrim($rr, '.');

            AliyunDns::aliyun($this->pool->aliyun)
                ->store($this->pool->root, $rr, $txtRecord->getValue(), DnsType::TXT);

            $challenge = $authorization->getDnsChallenge();
            $acme->validate($challenge);
        }

        sleep(10);

        if ($acme->isReady($order)) {
            $certificate = $acme->getCertificate($order);

            $cert = $this->pool->certificates()->create([
                'application_id' => $this->pool->application_id,
                'csr' => $certificate->getCsr(),
                'certificate' => $certificate->getCertificate(),
                'private_key' => $certificate->getPrivateKey(),
                'expired_at' => $certificate->getExpiryDate(),
            ]);

            match ($this->pool->type) {
                DomainType::MIDDLE => $this->deployToServer($cert),
                DomainType::PLAYER, DomainType::RANK => $this->deployToDcdn($cert),
                DomainType::STORAGE => $this->deployToCdn($cert),
            };
        }
    }

    public function deployToServer(Certificate $cert): void
    {
        $domain = str_replace('*.', '', $this->pool->domain);
        file_put_contents('/nginx/ssl/'.$domain.'_certificate.pem', $cert->certificate);
        file_put_contents('/nginx/ssl/'.$domain.'_private_key.pem', $cert->private_key);
    }

    public function deployToDcdn(Certificate $cert): void
    {
        AliyunDcdn::aliyun($this->pool->objectStorageService->aliyun)
            ->setCertificate($this->pool->domain, $cert->certificate, $cert->private_key);
    }

    public function deployToCdn(Certificate $cert): void
    {
        AliyunCdn::aliyun($this->pool->objectStorageService->aliyun)
            ->setCertificate($this->pool->domain, $cert->certificate, $cert->private_key);
    }
}
